#ifndef ALLOC_HOOK_H
#define ALLOC_HOOK_H

#include <sys/types.h>

#include <cstdint>

constexpr uint32_t MAX_STACK_LEN = 32U;
constexpr uint8_t ALLOC_IN_USE = 1U;
constexpr uint8_t MMAP_IN_USE = 2U;

/**
 * @brief The AllocRecord struct, which is used to record the allocation information.
 */
struct AllocRecord {
  void* p;                     // pointer to the memory
  pid_t pid;                   // process id
  uint32_t len;                // length of the memory
  void* stack[MAX_STACK_LEN];  // stack information
  uint32_t stack_len;          // length of the stack information
  uint8_t in_use;              // flag to indicate if the memory is in use
  AllocRecord* next;           // next allocation record

  AllocRecord() : p(nullptr), pid(0), len(0), stack_len(0), in_use(0), next(nullptr) {
    for (uint32_t i = 0; i < MAX_STACK_LEN; ++i) {
      stack[i] = nullptr;
    }
  }
};

/**
 * @brief The MmapRecord struct, which is used to record the mmap information.
 */
struct ThreadRecord {
  pid_t pid;            // process id
  char name[16];        // thread name
  uint32_t alloc_size;  // size of the allocation
  void* kstk_esp;       // kernel stack pointer
  ThreadRecord* next;   // next thread record

  ThreadRecord() : pid(0), alloc_size(0), kstk_esp(nullptr), next(nullptr) {
    for (uint32_t i = 0; i < sizeof(name); ++i) {
      name[i] = '\0';
    }
  }
};

/**
 * @brief The AllocDataHeader struct, which is used to record the header information of the allocation data.
 */
struct AllocDataHeader {
  uint32_t version;          // version of the data structure
  uint32_t heap_size;        // size of the heap
  uint32_t mmap_size;        // size of the mmap
  uint32_t alloc_list_size;  // size of the allocation list
  uint32_t smaps_file_len;   // length of the smaps file
  uint32_t thread_info_len;  // length of the thread information

  AllocDataHeader()
      : version(0), heap_size(0), mmap_size(0), alloc_list_size(0), smaps_file_len(0), thread_info_len(0) {
  }
};

#endif  // ALLOC_HOOK_H
